package ArchiveClasses;

import java.io.File;
import java.util.ArrayList;
import java.util.Scanner;

public class ArchiveOperations {

	private static ArrayList<Integer> NodesVector = new ArrayList<Integer>();
	private static ArrayList<ArrayList<Integer>> ListsVector = new ArrayList<ArrayList<Integer>>();
	private static int NUMBER_OF_EDGES = 0;
	private static int lastCase = 0;
	private static int pointer = 0;

	private static void createNodesVector(String archive) {
		Scanner arc = null;
		try {
			arc = new Scanner(new File(archive));
			int aux = pointer;
			while (aux != 0) {
				arc.nextInt();
				aux--;
			}
			NUMBER_OF_EDGES = arc.nextInt();
			aux = 2 * NUMBER_OF_EDGES;
			while (aux != 0) {
				int node = arc.nextInt();
				if (!NodesVector.contains(node))
					NodesVector.add(node);
				aux--;
			}
		} catch (Exception e) {
			System.out.println("Error on creating nodes' vector!\n" + e);
		} finally {
			if (arc != null)
				arc.close();
		}
	}

	private static void createListsVector(String archive) {
		Scanner arc = null;
		for (int i = 0; i < NodesVector.size(); i++)
			ListsVector.add(i, new ArrayList<Integer>());
		try {
			arc = new Scanner(new File(archive));
			int aux = pointer;
			while (aux != 0) {
				arc.nextInt();
				aux--;
			}
			arc.nextInt();
			aux = NUMBER_OF_EDGES;
			while (aux != 0) {
				int first_node = arc.nextInt(), second_node = arc.nextInt(), index = NodesVector
						.indexOf(first_node);
				ListsVector.get(index).add(second_node);
				aux--;
			}
		} catch (Exception e) {
			System.out.println("Error on creating lists' vector!\n" + e);
		} finally {
			if (arc != null)
				arc.close();
		}
		try {
			arc = new Scanner(new File(archive));
			int aux = pointer;
			while (aux != 0) {
				arc.nextInt();
				aux--;
			}
			arc.nextInt();
			aux = NUMBER_OF_EDGES;
			while (aux != 0) {
				int first_node = arc.nextInt(), second_node = arc.nextInt(), index = NodesVector
						.indexOf(second_node);
				ListsVector.get(index).add(first_node);
				aux--;
			}
		} catch (Exception e) {
			System.out.println("Error on creating lists' vector!" + e);
		} finally {
			if (arc != null)
				arc.close();
		}
	}

	private static void auxFinder(ArrayList<Integer> list, int TTL,
			ArrayList<Integer> ReachableNodes, ArrayList<Integer> excludedNodes) {
		for (Integer node : list) {
			if (TTL == 0)
				return;
			else {
				if (!ReachableNodes.contains(node)
						&& !excludedNodes.contains(node)) {
					ReachableNodes.add(node);
					excludedNodes.add(node);
				}
				auxFinder(ListsVector.get(NodesVector.indexOf(node)), TTL - 1,
						ReachableNodes, excludedNodes);
			}
		}
	}

	private static void findUnreachableNodes(String archive) {
		Scanner arc = null;
		try {
			arc = new Scanner(new File(archive));
			pointer += 2 * NUMBER_OF_EDGES + 1;
			int aux = pointer;
			while (aux != 0) {
				arc.nextInt();
				aux--;
			}
			boolean flag = true;
			do {
				int node = arc.nextInt();
				int TTL = arc.nextInt();
				if (node == 0 && TTL == 0) {
					flag = false;
				} else {
					ArrayList<Integer> list = ListsVector.get(NodesVector
							.indexOf(node));
					ArrayList<Integer> excludedNodes = new ArrayList<Integer>();
					ArrayList<Integer> ReachableNodes = new ArrayList<Integer>();
					ArrayList<Integer> UnreachableNodes = new ArrayList<Integer>();
					excludedNodes.add(node);
					auxFinder(list, TTL, ReachableNodes, excludedNodes);
					for (Integer element : NodesVector)
						if (!ReachableNodes.contains(element)
								&& element != node)
							UnreachableNodes.add(element);
					System.out.println("\n\nCase " + ++lastCase
							+ ": Unreachable Nodes from node " + node
							+ " with TTL " + TTL + ":\n" + UnreachableNodes);
				}
			} while (flag);
			if (!flag && arc.hasNext()) {
				if (arc.nextInt() != 0) {
					pointer += 2 * (lastCase + 1);
					NodesVector = new ArrayList<Integer>();
					ListsVector = new ArrayList<ArrayList<Integer>>();
					NUMBER_OF_EDGES = 0;
					read(archive);
				}
			}
		} catch (Exception e) {
			System.out.println("Error on finding reachable nodes!\n" + e);
		} finally {
			if (arc != null)
				arc.close();
		}
	}

	public static void read(String archive) {
		createNodesVector(archive);
		createListsVector(archive);
		findUnreachableNodes(archive);
	}

}
